package com.iretailer.report.easyexcel.listener;

import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.iretailer.report.common.InternationalMessage;
import com.iretailer.report.easyexcel.data.CompanyData;
import com.iretailer.report.error.ImportException;
import com.iretailer.report.model.*;
import com.iretailer.report.service.*;
import com.iretailer.report.util.GetId;
import com.iretailer.report.util.SecurityUserUtil;
import com.iretailer.report.util.SpringUtils;
import com.iretailer.report.util.TimeUtil;
import lombok.Getter;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpServletRequest;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @Auther Bennie
 * @Date 2020/7/17 16:54
 * @Description
 */
@Slf4j
public class CompanyDataListener extends AnalysisEventListener<CompanyData> {

    private final CompanyService companyService;

    private final CategoriesService categoriesService;

    private final MallsService mallsService;

    private final BusinessTimeService businessTimeService;

    private final UserMallService userMallService;

    private final User currentUser;

    private final String language;

    @Getter
    private List<CompanyData> companyDataList = new ArrayList<>();

    public CompanyDataListener(HttpServletRequest request) {
        currentUser = SecurityUserUtil.currentUser(request);
        language = SecurityUserUtil.userLanguage(request);
        this.mallsService = SpringUtils.getBean(MallsService.class);
        this.companyService = SpringUtils.getBean(CompanyService.class);
        this.categoriesService = SpringUtils.getBean(CategoriesService.class);
        this.businessTimeService = SpringUtils.getBean(BusinessTimeService.class);
        this.userMallService = SpringUtils.getBean(UserMallService.class);
    }

    @SneakyThrows
    @Override
    public void invoke(CompanyData data, AnalysisContext analysisContext) {

        // 公司代码不能为空
        String companyCode = data.getCompanyCode();
        if (StringUtils.isBlank(companyCode)) {
            throw new ImportException(InternationalMessage.EMPTY_COMPANY_CODE.getByLanguage(language));
        }

        // 公司名称不能为空
        String companyName = data.getCompanyName();
        if (StringUtils.isBlank(companyName)) {
            throw new ImportException(InternationalMessage.EMPTY_COMPANY_NAME.getByLanguage(language));
        }

        // 获取 案场名称
        String mallName = data.getMallName();
//        if (StringUtils.isBlank(mallName)) {
//            throw new ImportException(InternationalMessage.EMPTY_MALL_NAME.getByLanguage(language));
//        }


        // 案场不能重复的
        if (StringUtils.isNotEmpty(mallName) && mallsService.count(new QueryWrapper<Malls>().lambda().eq(Malls::getName, mallName)) > 0) {
            throw new ImportException(InternationalMessage.EXISTS_MALL_NAME.getByLanguage(language) + "【" + mallName + "】");
        }
//
//        String mallCode = data.getMallCode();
//        if (StringUtils.isBlank(mallCode)) {
//            throw new ImportException(InternationalMessage.EMPTY_MALL_CODE.getByLanguage(language));
//        }

        // 合同开始时间
        String startDate = data.getStartDate();
        if (StringUtils.isBlank(startDate)) {
            throw new ImportException(InternationalMessage.EMPTY_START_DATE.getByLanguage(language));
        }

        // 合同结束时间
        String endDate = data.getEndDate();
        if (StringUtils.isBlank(endDate)) {
            throw new ImportException(InternationalMessage.EMPTY_END_DATE.getByLanguage(language));
        }
        companyDataList.add(data);
    }

    private final Map<String, Companies> companyMap = new HashMap<>();

    @SneakyThrows
    @Override
    @Transactional
    public void doAfterAllAnalysed(AnalysisContext analysisContext) {
        if (CollectionUtils.isEmpty(companyDataList)) {
            throw new ImportException("Empty File");
        }
        for (Map.Entry<String, List<String>> entry : companyDataList.stream().map(CompanyData::getMallName).collect(Collectors.groupingBy(n -> n)).entrySet()) {
            if (entry.getValue().size() > 1) {
                throw new ImportException(InternationalMessage.DUPLICATE_MALL_NAME.getByLanguage(language) + "【" + entry.getKey() + "】");
            }
        }
        Categories importBasicData = categoriesService.selectCategoryByKeyName("ImportBasicData");
        if (importBasicData == null) {
            throw new ImportException("ImportBasicData Categories is null");
        }
        List<Categories> categories = categoriesService.selectCategoryByParentId(importBasicData.getId());
        Map<String, Categories> categoriesMap = categories.stream().collect(Collectors.toMap(Categories::getKeyName, a -> a));
        for (CompanyData companyData : companyDataList) {
            // 获取公司名称
            String companyName = companyData.getCompanyName();
            Companies company = companyMap.get(companyName);
            if (company == null) {
                // 没找到对应的公司，创建一个
                company = companyService.getOne(new QueryWrapper<Companies>().lambda().eq(Companies::getName, companyName));
                if (company == null) {
                    company = new Companies()
                            .setStatus(1)
                            .setCreateUser(currentUser.getName())
                            .setName(companyName).setId(GetId.UUID())
                            .setCreateTime(LocalDateTime.now())
                            .setCompanyCode(companyData.getCompanyCode());

                    if (!(companyService.saveOrUpdate(company))) {
                        throw new ImportException(String.format("Import company 【%s】fail;", companyName));
                    }
                }
                companyMap.put(companyName, company);
            }
            String companyId = company.getId();
            String mallName = companyData.getMallName();
            if (StringUtils.isNotEmpty(mallName)) {
                Malls mall = new Malls()
                        .setContractStartDate(TimeUtil.localDate_format(companyData.getContractStartDate()))
                        .setContractEndDate(TimeUtil.localDate_format(companyData.getContractEndDate()))
                        .setCreateTime(LocalDateTime.now()).setName(companyData.getMallName())
                        .setMallCode(companyData.getMallCode()).setCompanyId(companyId)
                        .setId(GetId.UUID()).setEnabled(1).setRanked(0).setOperationAcreage(0).setClerkNumber(0);
                // 城市
                Categories city = categoriesMap.get("City");
                if (city != null) {
                    mall.setCityId(city.getData());
                }
                // 时区
                Categories timezone = categoriesMap.get("DefaultTimeZone");
                if (timezone != null) {
                    mall.setTimeZone(timezone.getData());
                } else {
                    mall.setTimeZone("Etc/GMT-8");
                }
                mallsService.saveOrUpdate(mall);
                businessTimeService.insertBusinessTimeMalls(businessTime(companyData, companyId,
                        categoriesMap).getId(), Collections.singletonList(mall.getId()));
                if (!currentUser.getRoleId().equals("-")) {
                    userMallService.saveOrUpdate(new UserMall(currentUser.getId(), mall.getId(), 1));
                }
            }
        }
        log.info("Excel 用户数据导入成功!");
    }

    private BusinessTimes businessTime(CompanyData c, String companyId, Map<String, Categories> categoriesMap) {
        // 营业时间设置
        Categories timeType = categoriesService.selectCategoryByKeyName("OrdinaryType");
        BusinessTimes b = new BusinessTimes();
        b.setId(GetId.UUID());
        b.setCompanyId(companyId);
        b.setTimeType(timeType.getId());
        b.setTimeTypeName(timeType.getName());
        b.setWeekdays("Mon,Tue,Wed,Thu,Fri,Sat,Sun");
        b.setStartDate(c.getContractStartDate());
        b.setEndDate(c.getContractEndDate());
        Categories startTime = categoriesMap.get("StartTime");
        if (startTime != null) {
            b.setStartTime(TimeUtil.parse_LocalTime(startTime.getData()));
        } else {
            b.setStartTime(LocalTime.of(10, 0, 0));
        }
        Categories endTime = categoriesMap.get("EndTime");
        if (endTime != null) {
            b.setEndTime(TimeUtil.parse_LocalTime(endTime.getData()));
        } else {
            b.setEndTime(LocalTime.of(22, 0, 0));
        }
        businessTimeService.saveOrUpdate(b);
        return b;
    }

}
